package com.msmall.community.question.service.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.msmall.base.cache.CacheFactory;
import com.msmall.base.pager.PaginationSupport;
import com.msmall.base.service.impl.BaseManagerImpl;
import com.msmall.base.util.ConstantDB;
import com.msmall.base.util.Constants;
import com.msmall.community.common.CascadeCollection;
import com.msmall.community.common.service.CommendManager;
import com.msmall.community.common.util.FilterCharsUtil;
import com.msmall.community.dpt.model.Segment;
import com.msmall.community.klg.model.ArticleReply;
import com.msmall.community.question.dao.QuestionDao;
import com.msmall.community.question.model.Answer;
import com.msmall.community.question.model.Question;
import com.msmall.community.question.service.QuestionManager;
import com.msmall.community.question.util.QuestionUtil;
import com.msmall.community.user.model.UserInfo;
import com.msmall.community.user.model.UserSetting;
import com.msmall.community.user.service.UserManager;

public class QuestionManagerImpl extends BaseManagerImpl<Question, Long> implements QuestionManager{
	
	private static final Log log = LogFactory.getLog(QuestionManagerImpl.class);

	private QuestionDao questionDao;
	
	private UserManager userManager;
	
	private CommendManager commendManager;

	public void setQuestionDao(QuestionDao questionDao) {
		this.questionDao = questionDao;
	}

	public void setUserManager(UserManager userManager) {
		this.userManager = userManager;
	}
	
	public void setCommendManager(CommendManager commendManager) {
		this.commendManager = commendManager;
	}

	/**
	 * 验证Question.Answer content
	 * @return 1:正常；2字符太少；3字符太多;4含有非法字符
	 */
	public int validateAnswerContent(String content){
		int titleOK = QuestionUtil.checkQuestionAnswerLength(content);
		if(titleOK == 2){
			return 2;
		}
		if(titleOK == 3){
			return 3;
		}
		boolean titleC = FilterCharsUtil.containsFilterChars(content);
		if(titleC){
			return 4;
		}
		return 1;
	}
	
	/**
	 * 验证Question content
	 * @return 1:正常；2字符太少；3字符太多;4含有非法字符
	 */
	public int validateQuestionContent(String content){
		int titleOK = QuestionUtil.checkQuestionContentLength(content);
		if(titleOK == 2){
			return 2;
		}
		if(titleOK == 3){
			return 3;
		}
		boolean titleC = FilterCharsUtil.containsFilterChars(content);
		if(titleC){
			return 4;
		}
		return 1;
	}
	/**
	 * 增加查看问题次数
	 */
	public Question incrementQuestionClickAmount(Long questionid) throws Exception{
		try{
			Question q = (Question) questionDao.get(Question.class, questionid);
			q.setClickAmount(q.getClickAmount()==null?0:q.getClickAmount() + 1);
			q = (Question) questionDao.saveObject(q);
			return q;
		}catch(Exception e){
			log.debug(e);
			throw e;
		}
	}
	/**
	 * 同时增加问题回答数量
	 */
	public Answer saveQuestionAnswer(Answer a, Long userid, String uat) throws Exception{
		try{
			a.setCreateTime(new Date());
			a.setUserid(userid);
			a.setEnabled(ConstantDB.AVALIABLE);
			a.setSource(Constants.USER_AGENT_TYPE_WML.equalsIgnoreCase(uat)? ConstantDB.USER_AGENT_TYPE_WML :ConstantDB.USER_AGENT_TYPE_HTML);
			a = (Answer) questionDao.saveObject(a);
			
			Question q = (Question) questionDao.get(Question.class, a.getQuestionid());
			q.setAnswerAmount(q.getAnswerAmount()==null?0:q.getAnswerAmount() + 1);
			q = (Question) questionDao.saveObject(q);
			return a;
		}catch(Exception e){
			log.debug(e);
			throw e;
		}
	}
	public Question saveQuestion(Question q, Long userid, String uat) throws Exception{
		try{
			UserInfo user = userManager.getByUserid(userid);
			q.setAnswerAmount(0);
			q.setClickAmount(0);
			q.setCreateTime(new Date());
			q.setEnabled(ConstantDB.AVALIABLE);
			q.setLastModifyTime(new Date());
			q.setNickname(user.getNickname());
			q.setSource(Constants.USER_AGENT_TYPE_WML.equalsIgnoreCase(uat)? ConstantDB.USER_AGENT_TYPE_WML :ConstantDB.USER_AGENT_TYPE_HTML);
			q.setReply(ConstantDB.REPLY);
			q.setTerminal(ConstantDB.QUESTION_TERMINAL_NO);
			q = questionDao.save(q);
			return q;
		}catch(Exception e){
			log.debug(e);
			throw e;
		}
	}
	
	/**
	 * 获得提问的回复.enabed or not都选出
	 * @param page
	 * @param userid 当前登录系统的用户，用于分页的PAGESIZE
	 */
	public void getAnswerPaginationByQuestion(PaginationSupport page, Long userid, Long questionid) throws Exception{
		try{
			page.setClazz(ArticleReply.class);
			
			String queryString = "from Answer t where t.questionid = " + questionid;
			queryString += " order by createTime asc";
			page.setQueryString(queryString);
			questionDao.getPagination(page);
		}catch(Exception e){
			log.debug(e);
			throw e;
		}
	}
	
	/**
	 * 获得提问列表 enabled
	 * ConstantDB.QUESTION_TERMINAL_NO
	 */
	public void getQuestionPagination(PaginationSupport page, Long segmentid, int terminal) throws Exception{
		try{
			page.setClazz(Question.class);
			
			String queryString = "from Question q where q.enabled="+ConstantDB.AVALIABLE + " and q.type="+segmentid;
			if(ConstantDB.QUESTION_TERMINAL_NO == terminal){
				queryString = queryString + " and q.terminal=" + terminal;
			}else if(ConstantDB.QUESTION_TERMINAL_YES == terminal){
				queryString = queryString + " and q.terminal=" + terminal;
			}
			queryString += " order by q.createTime asc";
			page.setQueryString(queryString);
			questionDao.getPagination(page);
		}catch(Exception e){
			log.debug(e);
			throw e;
		}
	}
	
	/**
	 * 通过用户ID 获得此用户发表的提问
	 */
	public void getQuestionPaginationByUserid(PaginationSupport page, Long userid) throws Exception{
		try{
			String queryString = "from Question q where q.enabled="+ConstantDB.AVALIABLE + " and q.userid=" +userid + " ORDER BY q.questionid DESC";
			page.setQueryString(queryString);
			questionDao.getPagination(page);
		}catch(Exception e){
			log.error(e);
			throw e;
		}
	}
	
	/**
	 * 通过用户ID 获得此用户对提问的回答
	 */
	public void getAnswerPaginationByUserid(PaginationSupport page, Long userid) throws Exception{
		try{
			String queryString = "from Answer q where q.enabled="+ConstantDB.AVALIABLE + " and q.userid=" +userid + " ORDER BY q.answerid DESC";
			page.setQueryString(queryString);
			questionDao.getPagination(page);
		}catch(Exception e){
			log.error(e);
			throw e;
		}
	}
	
	/**
	 * 获得segment下点击数最多的问题 enabled
	 * containsChildren 是否统计segid
	 */
	public void getPaginationByClickAmount(PaginationSupport page, Long segid, boolean containsChildren) throws Exception{
		try{
			page.setClazz(Question.class);
			
			String queryString = "from Question q where q.enabled="+ConstantDB.AVALIABLE;
			StringBuffer buffer = new StringBuffer();
			if(containsChildren){
				buffer.append(" and q.type in (").append(segid);
				CascadeCollection<Segment> cs = (CascadeCollection<Segment>) CacheFactory.getInstance().getCache(Constants.CACHE_NAME_COMMON).get(Constants.CACHE_KEY_SEGMENT_CASCADECOLLECTION);
				CascadeCollection<Segment> current = cs.getAllDatas().get(segid);
				List<CascadeCollection<Segment>> children = current.getChildren();
				for(CascadeCollection<Segment> child : children){
					buffer.append(",").append(child.getCurrent().getSegmentid());
				}
				buffer.append(")");
			}else{
				buffer.append(" and q.type=").append(segid);
			}
			queryString += buffer.toString();
			queryString += " order by q.clickAmount desc";
			page.setQueryString(queryString);
			questionDao.getPagination(page);
		}catch(Exception e){
			log.debug(e);
			throw e;
		}
	}
	/**
	 * 根据顶层问题分类包括相应的子分类，查询出点击数最高的amount个问题。pagination不统计总数
	 * 由JOB每1小时执行一次
	 */
	public void refreshQuestionByClickAmount(int amount){
		try{
			Map<Long, List<Question>> maps = new HashMap<Long, List<Question>>();
			CascadeCollection<Segment> cs = (CascadeCollection<Segment>) CacheFactory.getInstance().getCache(Constants.CACHE_NAME_COMMON).get(Constants.CACHE_KEY_SEGMENT_CASCADECOLLECTION);
			CascadeCollection<Segment> top = cs.getAllDatas().get(ConstantDB.SEGMENT_ID_QUESTION_NAV);
			List<CascadeCollection<Segment>> children = top.getChildren();
			for(CascadeCollection<Segment> child : children){
				Long segid = child.getCurrent().getSegmentid();
				PaginationSupport page = new PaginationSupport();
				page.setAutoCount(false);
				page.setPageIndex(0);
				page.setPageSize(amount);
				getPaginationByClickAmount(page, segid, true);
				maps.put(segid, page.getItems());
			}
			CacheFactory.getInstance().getCache(Constants.CACHE_NAME_COMMON).put(Constants.CACHE_KEY_QUESTION_HOT, maps);
		}catch(Exception e){
			log.debug(e);
		}
	}
	/**
	 * 用户是否被授权推荐问答
	 */
	public boolean isAuthorizedCommend(Long userid){
		try{
			UserSetting setting = userManager.getSetting(userid, ConstantDB.USER_SETTING_KEY_COMMEND_QUESTION);
			if(setting == null)
				return false;
			if(ConstantDB.USER_SETTING_VALUE_COMMEND_QUESTION_TOP.equals(setting.getPropertyValue())){
				return true;
			}
		}catch(Exception e){
			log.debug(e);
		}
		return false;
	}
	/**
	 * 用户是否被授权删除问答/回复
	 */
	public boolean isAuthorizedRemove(Long userid){
		try{
			UserSetting setting = userManager.getSetting(userid, ConstantDB.USER_SETTING_KEY_REMOVE_QUESTION);
			if(setting == null)
				return false;
			if(ConstantDB.USER_SETTING_VALUE_REMOVE_QUESTION_TOP.equals(setting.getPropertyValue())){
				return true;
			}
		}catch(Exception e){
			log.debug(e);
		}
		return false;
	}
	
	/**
	 * 删除问答
	 */
	public Question delQuestion(Long userid, Long questionid) throws Exception {
		try{
			Question question = (Question) questionDao.get(Question.class, questionid);
			if(isAuthorizedRemove(userid)){
				question.setEnabled(ConstantDB.UNAVALIABLE);
				question = (Question) questionDao.saveObject(question);
			}
			return question;
		}catch(Exception e){
			throw e;
		}
	}
	/**
	 * 删除问答回复
	 */
	public Answer delAnswer(Long userid, Long answerid) throws Exception{
		try{
			Answer answer = (Answer) questionDao.get(Answer.class, answerid);
			if(isAuthorizedRemove(userid)){
				answer.setEnabled(ConstantDB.UNAVALIABLE);
				answer = (Answer) questionDao.saveObject(answer);
			}
			return answer;
		}catch(Exception e){
			throw e;
		}
	}
	
}
